import log4js from 'log4js'
import fs from 'fs'
import logConfig, { logDir } from '../../config/config.logs'

// 确保日志目录存在
if (!fs.existsSync(logDir)) {
  fs.mkdirSync(logDir, { recursive: true })

  console.log(`日志目录已创建: ${logDir}。。。`)
}

// 配置log4js
log4js.configure(logConfig)

/**
 * 统一日志管理类
 */
export class Logger {
  /**
   * 获取指定分类的logger实例
   * @param category 日志分类
   * @returns logger实例
   */
  public static getLogger(category: string = 'default'): log4js.Logger {
    return log4js.getLogger(category)
  }

  /**
   * 获取默认logger实例
   */
  public static get default(): log4js.Logger {
    return this.getLogger()
  }

  /**
   * 获取错误logger实例
   */
  public static get error(): log4js.Logger {
    return this.getLogger('error')
  }

  /**
   * 获取数据库logger实例
   */
  public static get database(): log4js.Logger {
    return this.getLogger('database')
  }

  /**
   * 获取HTTP请求logger实例
   */
  public static get http(): log4js.Logger {
    return this.getLogger('http')
  }

  /**
   * 创建控制器专用logger
   * @param controllerName 控制器名称
   */
  public static getControllerLogger(controllerName: string): log4js.Logger {
    return this.getLogger(`controller.${controllerName}`)
  }

  /**
   * 创建服务专用logger
   * @param serviceName 服务名称
   */
  public static getServiceLogger(serviceName: string): log4js.Logger {
    return this.getLogger(`service.${serviceName}`)
  }

  /**
   * 安全序列化对象，避免循环引用
   * @param obj 要序列化的对象
   * @returns 序列化后的字符串
   */
  public static safeStringify(obj: any): string {
    try {
      // 使用replacer函数处理循环引用
      const seen = new WeakSet()
      return JSON.stringify(obj, (key, value) => {
        if (key === 'password' || key === 'token') {
          return '******'
        }
        if (typeof value === 'object' && value !== null) {
          if (seen.has(value)) {
            return '[Circular]'
          }
          seen.add(value)
        }
        return value
      })
    } catch (error: any) {
      return String(error || '无法序列化的对象')
    }
  }

  /**
   * 获取Koa请求上下文的日志信息
   * @param ctx Koa上下文
   * @returns 格式化的请求信息
   */
  public static getRequestLogInfo(ctx: any): Record<string, any> {
    return {
      method: ctx.method,
      url: ctx.url,
      path: ctx.path,
      query: ctx.query,
      ip: ctx.ip,
      headers: {
        'user-agent': ctx.headers['user-agent'],
        'content-type': ctx.headers['content-type']
      }
    }
  }
}

// 导出默认实例
export default Logger
